// This file is part of the ustl library, an STL implementation.
//
// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
//
// \file stdtest.cc
// \brief Standard BVT harness.
//


#include <stdlib.h>
#include <stdio.h>
#include <e32base.h>
#include <e32cons.h>
#include <reent.h> // CloseSTDLIB
#include <ustl.h>
#include "stdtest.h"

dbgstream ustl::Cout;

_LIT(KTxtEPOC32EX,"EPOC32EX");
_LIT(KTxtExampleCode,"USTL Test");
_LIT(KFormatFailed,"failed: leave code=%d");
_LIT(KTxtOK,"ok");
_LIT(KTxtPressAnyKey," [press any key]");

string* TestFile;

LOCAL_C void callExampleL();
LOCAL_C int Main( int argc, char** argv); 

static void InitOutputFile( const char* testFile )
{
	*TestFile = testFile;
	int biggest;
	cout << "Heap available " << User::Heap().Available(biggest) << endl;
	cout << "Biggest Block " << biggest << endl;
}

static void WriteOutput()
{
	int biggest;
	cout << "Heap available " << User::Heap().Available(biggest) << endl;
	cout << "Biggest Block " << biggest << endl;
	
	cout.flush( *TestFile );
}

// public
CConsoleBase* console; // write all your messages to this

GLDEF_C TInt E32Main() // main function called by E32
    {
	__UHEAP_MARK;
	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
	TRAPD(error,callExampleL()); // more initialization, then do example
	__ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
	//CloseSTDLIB();
	delete cleanup; // destroy clean-up stack
	__UHEAP_MARKEND;
	return 0; // and return
    }

LOCAL_C void callExampleL() // initialize and call example code under cleanup stack
    {
	console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
	CleanupStack::PushL(console);
	char* initStrings = "Application";
	TRAPD(error,(void)Main( 1, &initStrings )); // perform example function
	if (error)
		console->Printf(KFormatFailed, error);
	else
		console->Printf(KTxtOK);
	console->Printf(KTxtPressAnyKey);
	console->Getch(); // get and ignore character
	CleanupStack::PopAndDestroy(); // close console
    }

#undef MEMORY_CHECKING

#ifndef MEMORY_CHECKING

_LIT( KSayTest, "." );
#define SAY_TEST( num, function ) console->Printf( KSayTest)

#ifdef __WINS__
#define FILEPART1 "c:\\bvt"
#else
#define FILEPART1 "c:\\data\\bvt"
#endif
#define FILEPART3 ".std"
#define TEST( aTestNum, aFunction ) try { SAY_TEST( aTestNum, aFunction ); \
	InitOutputFile( FILEPART1 #aTestNum FILEPART3 ); \
	aFunction(); WriteOutput(); } \
	catch (ustl::exception& e) { console->Printf( _L("Exception thrown: %s\n"), e.what() ); }

#else // MEMORY_CHECKING

#define P(x) console->Printf( _L(x) )
#define P2(x, y) console->Printf( _L(x), y )
#define TEST( aTestNum, aFunction ) { \
	P(#aFunction); \
	TInt i=0; \
	for (TInt err=KErrNoMemory; err==KErrNoMemory; i++) \
	{ \
		__UHEAP_MARK; \
		__UHEAP_FAILNEXT(i); \
		TRAP( err, aFunction() ); \
		InitOutputFile( ""); \
		__UHEAP_MARKEND; \
	} \
	P2( ": %d\n", i ); }
#endif

int Main( int , char** )
{
	string testFile;
	TestFile = &testFile;

#ifdef MEMORY_CHECKING
	// Various things to ensure that all Symbian memory is pre-allocated:
	TRAPD( dummy, User::LeaveNoMemory() ); // User::LeaveNoMemory allocates memory!!
	InitOutputFile( "");  
	TestCML(); // Initial dummy run - stdlib sprintf allocates memory
	InitOutputFile(""); // Reset
#endif

	int rv = EXIT_SUCCESS;	
	TEST( 00, TestCML );
	TEST( 01, TestML );
	TEST( 02, TestMB );
	TEST( 03, TestStreams );
	TEST( 04, TestVector );
	TEST( 05, TestAlgorithms );// armv5 problem
	TEST( 06, TestObjectVector );
	TEST( 07, TestString );	// mem leak
	TEST( 08, TestStringVector );
	TEST( 09, TestStringStreams );
	TEST( 10, TestFunctors );
	TEST( 11, TestSetAndMultiset );
	TEST( 12, ObjectSerialization );
	//TEST( 13, TestCoutCinCerr );
	TEST( 14, TestMap );
	TEST( 15, TestMultiMap );	// armv5 problem
	TEST( 16, TestUTF8 );
	TEST( 17, TestBitset );
	TEST( 18, TestIntegralTuples );
	TEST( 19, TestEnumArithmetic );
	TEST( 20, TestStackAndQueue );
	TEST( 21, TestUtility );
	TEST( 22, TestMatrixAlgorithms );
	TEST( 23, TestSimdAlgorithms );
	TEST( 24, TestHeapOperations );
	TEST( 25, TestFStream );
	TEST( 26, TestLeaves );
	TEST( 27, TestSP );
	// Prevent Symbian signalling memory leaks from static strings:
	cout.flush();

    return (rv);
}
